package com.kent.hellokotlin.cClassAndObject

//可见性修饰符
/*
类、对象、接口、构造函数、方法、属性和它们的 setter 都可以有 可见性修饰符。 （getter 总是与属性有着相同的可见性。）
在 Kotlin 中有这四个可见性修饰符：private、 protected、 internal 和 public。 如果没有显式指定修饰符的话，默认可见性是 public。
*/

//包
/*函数、属性和类、对象和接口可以在顶层声明，即直接在包内：*/
fun baz() {}

class Bar { /*……*/ }
/*
如果你不指定任何可见性修饰符，默认为 public，这意味着你的声明将随处可见；
如果你声明为 private，它只会在声明它的文件内可见；
如果你声明为 internal，它会在相同模块内随处可见；
protected 不适用于顶层声明
*/

//例如
private fun foo() {} // 在 dVisibilityModifier.kt 内可见

public var bar: Int = 5 // 该属性随处可见
    private set         // setter 只在 dVisibilityModifier.kt 内可见

internal val baz = 6    // 相同模块内可见

//类和接口
/*对于类内部声明的成员：*/
/*
private 意味着只在这个类内部（包含其所有成员）可见；
protected—— 和 private一样 + 在子类中可见。
internal —— 能见到类声明的 本模块内 的任何客户端都可见其 internal 成员；
public —— 能见到类声明的任何客户端都可见其 public 成员。
*/
/*请注意在 Kotlin 中，外部类不能访问内部类的 private 成员。*/
/*如果你覆盖一个 protected 成员并且没有显式指定其可见性，该成员还会是 protected 可见性。*/
open class Outer {
    private val a = 1
    protected open val b = 2
    internal val c = 3
    val d = 4

    protected class Nested {
        public val e = 5
    }
}

class SubClass : Outer() {
    fun visible() {
        //a 不可见
        b
        c
        d
        Nested().e
    }

    override val b = 5
}

class Unrelated(val outer: Outer) {
    fun visible() {
        //outer.a 不可见
        //outer.b 不可见
        outer.c
        outer.d
        //Outer.Nested 不可见，Nested::e 也不可见
    }
}

//构造函数
/*要指定一个类的的主构造函数的可见性，使用以下语法（注意你需要添加一个显式 constructor 关键字）：*/
class C1 private constructor(a: Int) {/**/ }
class C2 internal constructor(a: Int) {/**/ }
open class C3 protected constructor(a: Int) {/**/ }

